package marcis.jarina.directory.repository;


import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Author: Jan Marcis
 * Date: 21.1.11
 * Time: 15:42
 */
public class OptimizedResources {

    private static final Logger log = Logger.getLogger("marcis.jarina.OptimizedResources");

    private final String jarFileName;

    public OptimizedResources(String jarFileName) {
        this.jarFileName = jarFileName;
    }

    public List<String> getEntries() {
        List<String> list = new ArrayList<String>(20);
        try {
            FileInputStream fis = new FileInputStream(jarFileName);
            ZipInputStream zis = new ZipInputStream(fis);
            ZipEntry ze;
            while ((ze = zis.getNextEntry()) != null) {
                String className = getClassNameFromJar(ze.getName());
                if (className != null) {
                    list.add(className);
                }
                zis.closeEntry();
            }
            zis.close();
        } catch (FileNotFoundException e) {
            log.error("Jar file was not found: " + jarFileName, e);
            return null;
        } catch (IOException e) {
            log.error("Error retrieving jar file content.", e);
            return null;
        }
        return list;
    }

    /**
     * @param jarResourceName name of resource in jar
     * @return fully classified java name
     */
    private String getClassNameFromJar(String jarResourceName) {
        final String suffix = ".class";
        if (!jarResourceName.contains(suffix)) {
            return null;
        }
        return jarResourceName.replace(suffix, "").replace("/", ".");
    }

    public String getJarFileName() {
        return jarFileName;
    }

    /**
     * @return all fully classified class names from class-jar
     */
    public Set<String> getFullClassNames() {
        if (this.jarFileName == null) {
            throw new NullPointerException("Java class can not contain zipped classes as jar do.");
        }
        return getClassNameFromJar(getEntries());
    }

    /**
     * @param set set of jar resource names
     * @return set of fully classified java names
     */
    private Set<String> getClassNameFromJar(List<String> set) {
        HashSet<String> result = new HashSet<String>();
        for (String one : set) {
            String brandNew = getClassNameFromJar(one);
            if (brandNew != null) {
                result.add(brandNew);
            }
        }
        return result;
    }


}
